package org.phona.object;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.phona.index.IndexNode;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.util.Log;

public class ContactManager {


	List<Contact> contactList=new ArrayList<Contact>();
	//Map<String,String> contactMap=new HashMap<String,String>();
	Set<Contact> filtredContactSet = new HashSet<Contact>();
	
	List<Contact> filtredContactList = new ArrayList<Contact>();
	Map<String,List<String>> filtredContactIdMap = new HashMap<String,List<String>>() ;

	IndexNode rootIndexNode;
	String filter=null;

	Map<Character,Character> charToNumber=new HashMap<Character,Character>();
	Map<String,String> numberToChar=new HashMap<String,String>();
	//ContactDbHelper dbAdapter=null;

	public static final String TAG = "ConctactManager";

	Context context;
	Map<String, Contact> idToContact = new HashMap<String, Contact>();

	public ContactManager(Context context){
		this.context = context;

		charToNumber.put(' ','1');
		charToNumber.put('a','2');
		charToNumber.put('b','2');
		charToNumber.put('c','2');

		charToNumber.put('d','3');
		charToNumber.put('e','3');
		charToNumber.put('d','3');

		charToNumber.put('g','4');
		charToNumber.put('h','4');
		charToNumber.put('i','4');

		charToNumber.put('j','5');
		charToNumber.put('k','5');
		charToNumber.put('l','5');

		charToNumber.put('m','6');
		charToNumber.put('n','6');
		charToNumber.put('o','6');

		charToNumber.put('p','7');
		charToNumber.put('q','7');
		charToNumber.put('r','7');
		charToNumber.put('s','7');

		charToNumber.put('t','8');
		charToNumber.put('u','8');
		charToNumber.put('v','8');

		charToNumber.put('w','9');
		charToNumber.put('x','9');
		charToNumber.put('y','9');
		charToNumber.put('z','9');

		numberToChar.put("0".intern()," ");
		numberToChar.put("1".intern()," ");
		numberToChar.put("2".intern(),"AaàBbCcç");
		numberToChar.put("3".intern(),"DdEeéèêëFf");
		numberToChar.put("4".intern(),"GgHhIiîï");
		numberToChar.put("5".intern(),"JjKkLl");
		numberToChar.put("6".intern(),"MmNnOoöô");
		numberToChar.put("7".intern(),"PpQqRrSs");
		numberToChar.put("8".intern(),"TtuüûùVv");
		numberToChar.put("9".intern(),"WwXxYyZz");

		rootIndexNode = new IndexNode();

	}

	public void init(){
		contactList.clear();
		//contactMap.clear();
		filtredContactList.clear();
		filtredContactSet.clear();
		filtredContactIdMap.clear();
		Long start = System.currentTimeMillis();
		fillConcats();
		Log.i(TAG,"Loading contacts in :"+(System.currentTimeMillis()-start));
		
	}

	void fillConcats(){
		ContentResolver cr = context.getContentResolver();
		Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
				new String[] {ContactsContract.Contacts._ID,ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts.HAS_PHONE_NUMBER},
				null, 
				null, 
				ContactsContract.Contacts.DISPLAY_NAME + " ASC");
		if (cur.getCount() > 0) {
			while (cur.moveToNext()) {
				String id = cur.getString(
						cur.getColumnIndex(ContactsContract.Contacts._ID));
				id=id.intern();
				String name = cur.getString(
						cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
				if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
					Contact current = new Contact(id,name);
					contactList.add(current);
					idToContact.put(id,current);							
					//contactMap.put(name.toLowerCase().intern(),id.intern());
					rootIndexNode.insert(name, id.intern());
				}

			}
		}
		cur.close();

		Cursor c = cr.query(
				ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
				new String[] {Phone.CONTACT_ID,Phone.NUMBER,Phone.TYPE, Phone.LABEL,Phone.IS_PRIMARY}, 
				null,
				null,
				null);
		String id;
		String label;
		String type;
		String phoneNumber; 
		String primary;
		while (c.moveToNext()) {
			id = c.getString(c.getColumnIndex(Phone.CONTACT_ID));

			//Log.i(TAG,"found phone "+phoneNumber);
			//Contact current = contactMap.get(name.toLowerCase().intern());
			//rootIndexNode.insert(phoneNumber, current);
			Contact contact = idToContact.get(id.intern());
			if(contact!=null){
				label = c.getString(c.getColumnIndex(Phone.LABEL));
				type = c.getString(c.getColumnIndex(Phone.TYPE));
				phoneNumber = c.getString(c.getColumnIndex(Phone.NUMBER));
				primary = c.getString(c.getColumnIndex(Phone.IS_PRIMARY));
				contact.addPhone(label,type,phoneNumber,primary);
			}
			//current.add(phoneNumber);
			//Log.i(TAG,"name:"+name+" label:"+label+" type:"+type+" num:"+phoneNumber+" primary:"+primary);
		}
		c.close();
	}

	public int getCount() {

		return filter==null?contactList.size():filtredContactList.size();
	}

	public Contact getItem(int position) {
		Log.i(TAG,"gettingItem pos="+position);	
		return filter==null?contactList.get(position):filtredContactList.get(position);
	}
	




	public void filter(String filter){
		filtredContactSet.clear();
		filtredContactList.clear();	
		filtredContactIdMap.clear();
		if(filter.length()==0){
			this.filter=null;
		}else{
			this.filter=filter;
			/*rootIndexNode.search(filter, filtredContactSet);
			filtredContactList.addAll(filtredContactSet);			
			Log.i(TAG, "resultFound "+filtredContactSet);*/
			rootIndexNode.search(toQueryList(filter), filtredContactIdMap);
			
			for(String id : filtredContactIdMap.keySet()){
				Contact c = idToContact.get(id.intern());
				filtredContactList.add(c);
			}
		}
	}



	List<String> toQueryList(String queryNumber) {
		List<String> result = new ArrayList<String>();
		for(Integer i=0,n=queryNumber.length();i<n;i++){
			result.add(numberToChar.get(queryNumber.substring(i,i+1).intern()));
		}
		return result;
	}

	String encode(String name){
		String result = "";
		//String accentRemovedName = StringOperation.sansAccent(name);
		String accentRemovedName = name;
		for(Character c : accentRemovedName.toCharArray()){
			result+=getHash(c);
		}
		return result;

	}

	Character getHash(Character c){
		Character m = Character.toLowerCase(c);
		return charToNumber.get(m);


	}

	Cursor getContactsFromContentProvider(){

		Cursor c = context.getContentResolver().query(Data.CONTENT_URI,
				new String[] {Data._ID,Data.DISPLAY_NAME, Phone.NUMBER,Phone.TYPE, Phone.LABEL,Phone.IS_PRIMARY},
				Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "' AND "+
				ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1' "


				/*Phone.TYPE+"='"+Phone.TYPE_HOME+"' AND "+
				Data.DISPLAY_NAME+" like '%si%'"*/,
				null, null);
		return c;
	}

	public boolean isFilterEnabled() {
		return filter!=null;
	}

	public List<String> getMatchedString(Contact contact) {
		// TODO Auto-generated method stub
		return filtredContactIdMap.get(contact.getId());
	}


}
